package bachelor.view {
	import CustomEvent.CustomEvent;

	import bachelor.Globals;

	import gs.TweenLite;
	import gs.easing.Strong;

	import flash.display.MovieClip;
	import flash.events.Event;
	import flash.geom.ColorTransform;

	/**
	 * @author Johannes
	 */
	public class Feedback extends MovieClip 
	{
		
////////////////////////////////////////////////////////////////////////////////
/////// VARIABLES //////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////

		// Layout
		private var _id : int;
		private var _startRotation : int;
		private var _tintColorIndex : int;
		private var _tintColor : uint;

		// Layer
		private var _activeGrid : int = 4;
		/*
		 * Derzeit angezeigte und klickbare Ebene
		 */
		private var _currentLayerIndex 	: Number = 0;
		/*
		 * Zuletzt gesehene, jetzt nicht mehr klickbare Ebene
		 */
		private var _lastLayerIndex : Number = -1; 
		
		
		// Scala
		private var _border : MovieClip = new MovieClip();
		private var _scala 		: MovieClip = new MovieClip();
		private var _verlauf 	: MovieClip = MovieClip(new verlaufMC()); 
		private var _lastVerlaufRotation : int;
		private var _slider 	: MovieClip = MovieClip(new sliderMC());
		private var _bounceThredsholdScala : Number = 360 / 48 * _activeGrid;

		// new Events
		public static const SCALA_VERLAUF_ROTATED : String = "scalaVerlaufRotated";
		public static const FEEDBACK_DEINITIALIZED : String = "feedbackDeinitialized";
		

////////////////////////////////////////////////////////////////////////////////
/////// CONSTRUCTOR ////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
		public function Feedback(p_id : int, p_startRotation : Number, p_tintColorIndex : int) 
		{
			trace("Feedback init ...");
			_id = p_id;
			_startRotation = Math.round(p_startRotation);
			_tintColorIndex = p_tintColorIndex;
			_tintColor = Globals.countryColorArray[p_tintColorIndex][1];
			
			init();
		}

////////////////////////////////////////////////////////////////////////////////
/////// METHODS ////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////


/////// INIT ///////////////////////////////////////////////////////////////////
		private function init() : void 
		{
			trace("Feedback -> init() ...");

			
			// Grafisches Feedback für "Country Fiducial gelegt"
			/*
			 * Hintergrund
			 */
			var _borderBg : MovieClip = MovieClip(new borderBgMC());
			_border.addChild(_borderBg);
			/* 
			 * Outline
			 */
			_border.graphics.lineStyle(3, _tintColor, 1);
			_border.graphics.drawCircle(0, 0, 60);
			_border.alpha = 0;
			addChild(_border);
			
			showBorder();

			
			// Scala generieren, aber noch ausgeblendet lassen 
			/*
			 *  Rahmen (momentan mit Hilfslinien)
			 */
			var _arrow : MovieClip = MovieClip(new arrowMC());
			/*
			 * Verlauf colorieren
			 */ 
			var verlaufColorTransform : ColorTransform = _verlauf.transform.colorTransform;
			verlaufColorTransform.color = _tintColor;
			_verlauf.transform.colorTransform = verlaufColorTransform;
			/*
			 * Gesamte Scala 
			 */ 
			_scala.addChild(_verlauf);
			_scala.addChild(_slider);
			_scala.addChild(_arrow);
			_scala.rotation = -90;
			_scala.alpha = 0;
			addChild(_scala);

		}
		

/////// DEINIT /////////////////////////////////////////////////////////////////
		public function deinitializeFeedback() : void
		{
			hideScala();
			hideBorder();
		}
		

////////////////////////////////////////////////////////////////////////////////
/////// BORDER /////////////////////////////////////////////////////////////////


/////// Border einblenden //////////////////////////////////////////////////////
		private function showBorder() : void 
		{
			trace("Feedback -> showBorder() ...");
			TweenLite.to(_border, Globals.fadeOutTime, {alpha:1, ease:Strong.easeOut});
		}

/////// Border ausblenden //////////////////////////////////////////////////////
		private function hideBorder() : void 
		{
			trace("Feedback -> hideBorder() ...");
			/*
			 * Das Ausblenden der Border bedeutet zwangsläufig, 
			 * dass der Fiducial entfernt wurde. 
			 * Dieses Feedback-Object deshalb removen lassen. 
			 */
			TweenLite.to(_border, Globals.fadeOutTime, {alpha:0, ease:Strong.easeOut, onComplete: onFeedbackDeinitialized});
		}
		
		private function onFeedbackDeinitialized() : void 
		{
			trace("Feedback -> onFeedbackDeinitialized() ...");
			dispatchEvent(new Event(FEEDBACK_DEINITIALIZED));
		}
		

		
	

////////////////////////////////////////////////////////////////////////////////
/////// SCALA //////////////////////////////////////////////////////////////////

		
/////// Scala einblenden ///////////////////////////////////////////////////////
		public function showScala() : void
		{
			trace("Feedback -> showScala() ...");
			TweenLite.to(_scala, Globals.fadeOutTime, {alpha:1, ease:Strong.easeOut});
		}
/////// Scala ausblenden ///////////////////////////////////////////////////////
		public function hideScala() : void 
		{
			trace("Feedback -> hideScala() ....");
			TweenLite.to(_scala, Globals.fadeOutTime, {alpha: 0, ease:Strong.easeOut});
		}


		
/////// Scala drehen, wenn Fiducial gedreht ////////////////////////////////////
		public function setScalaRotation(p_evt : CustomEvent) : void
		{		
//			trace("Feedback -> setScalaRotation() ...");
			/*
			 * Bogenmass in Winkel(Grad) umrechnen
			 * Mehrfachumdrehungen herausrechnen
			 * Winkeldifferenz = | aktueller Fiducialwinkel - letzter eingerastete Skalawinkel |
			 */ 
			var fiducialAngle 		: Number = int(p_evt.data.angle*360/(2*Math.PI)) + 180 - _startRotation;
			var fiducialAngleIn360 	: Number = (fiducialAngle % 360);
			var currentVerlaufAngleIn360 	: Number = ((360 + _verlauf.rotation) % 360);
			var diffAngle 			: Number = Math.abs(fiducialAngleIn360 - currentVerlaufAngleIn360);
			/*
			 * trace("=============================================== _verlauf.rotation : " + _verlauf.rotation);
			 * trace("=============================================== verlaufAngle      : " + verlaufAngle);
			 * trace("=============================================== fiducialAngleIn360: " + fiducialAngleIn360);
			 */
			_slider.rotation = fiducialAngleIn360;

			if( diffAngle > _bounceThredsholdScala ) 
			{
				// FIXME:  Verlauf springt ZWEI layerSteps bei "Überdrehen" bzw. "Unterdrehen" => Richtungsabfrage
				if(_lastVerlaufRotation < fiducialAngleIn360) {
					_currentLayerIndex = Math.floor(fiducialAngleIn360 / _bounceThredsholdScala); 	// abrunden
				} else {
					_currentLayerIndex = Math.ceil(fiducialAngleIn360 / _bounceThredsholdScala); 	// aufrunden
				}
//				trace("Feedback -> setScalaRotation() ::: _currentLayerIndex: " + _currentLayerIndex + " von 12");
				
				var dataArray : Array = [_currentLayerIndex, _lastLayerIndex];
				dispatchEvent(new CustomEvent(SCALA_VERLAUF_ROTATED, dataArray));
				
				var newVerlaufAngle : Number = _currentLayerIndex * _bounceThredsholdScala;
				
				_verlauf.rotation = newVerlaufAngle;
				
				_lastLayerIndex = _currentLayerIndex;
				_lastVerlaufRotation = newVerlaufAngle;
				
			}
			
		}	
		
		
////////////////////////////////////////////////////////////////////////////////
/////// getters & setter ///////////////////////////////////////////////////////
		
		public function getID() : int 
		{
			return _id;
		}

		public function getStartRotation() : int 
		{
			return _startRotation;
		}

		public function getTintColorIndex() : int 
		{
			return _tintColorIndex;
		}


		
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
	}
}
